package com.farmlei.facereg.common.base;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.farmlei.facereg.common.utils.DateUtils;
import com.farmlei.facereg.common.utils.PropertiesUtils;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.configuration.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;


/**
 * Controller父类
 */
@Controller
public class SuperController {
    /**
     * 日志对象
     */
    protected Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 上传文件，文件重命名，重命名规则：到毫秒的时间戳+三位随机数
     * @param file  要上传的文件
     * @param dirPath 上传的目录
     * @return 服务器文件目录+文件名
     * @throws Exception 异常
     */
    protected String uploadFileRename(MultipartFile file, String dirPath) throws Exception {
        Configuration config = PropertiesUtils.getConfig();
        String filePath = config.getString("fileRoute") + dirPath;
        String relativePath = filePath.substring(filePath.indexOf("/"));
        File fileAdress = new File(filePath);
        //如果文件夹不存在则创建
        if (!fileAdress .exists() && !fileAdress .isDirectory()) {
            fileAdress.mkdirs();
        }

        //获取后缀名
        String originalName = file.getOriginalFilename();
        String suffix = originalName.substring(originalName.lastIndexOf(".") + 1);

        //重命名文件，使用时间戳+随机数防止重复
        // 设置上传文件名
        SimpleDateFormat fileFormatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        // 源文件重命名,文件命名格式:yyyyMMddHHmmssSSS
        String fileName = fileFormatter.format(new Date()) + new Random().nextInt(1000) + "." + suffix;

        filePath = filePath + fileName;
        // 转存文件
        file.transferTo(new File(filePath));

        if (logger.isDebugEnabled()) {
            logger.debug("文件 [{}] 上传成功，目录 [{}]", originalName, filePath);
        }

        return relativePath + fileName;

    }

    /**
     * 上传图片，文件重命名，重命名规则：到毫秒的时间戳+三位随机数；并且压缩处理
     * @param file  要上传的文件
     * @param dirPath 上传的目录
     * @param compKB 压缩后的最大尺寸，单位KB，如果为0，表示不压缩
     * @return 服务器文件目录+文件名
     * @throws Exception 异常
     */
    protected String uploadImgRenameAndComp(MultipartFile file, String dirPath, int compKB) throws Exception {
        if (file == null) {
            return null;
        }
        //获取后缀名
        String originalName = file.getOriginalFilename();
        String suffix = originalName.substring(originalName.lastIndexOf(".") + 1);
        if (!"jpg".equalsIgnoreCase(suffix) && !"jpeg".equalsIgnoreCase(suffix) && !"png".equalsIgnoreCase(suffix)
                &&!"gif".equalsIgnoreCase(suffix)) {
            throw new Exception("图片格式不正确");
        }

        Configuration config = PropertiesUtils.getConfig();
        String filePath = config.getString("fileRoute") + dirPath;
        //按日期存放
        String dateDir = DateUtils.formatDate(new Date(), "yyyyMMdd");
        filePath += dateDir + "/";
        //针对windows环境，获取相对路径
        String relativePath = filePath.substring(filePath.indexOf("/"));
        File fileAdress = new File(filePath);
        //如果文件夹不存在则创建
        if (!fileAdress.exists() && !fileAdress.isDirectory()) {
            fileAdress.mkdirs();
        }

        //重命名文件，使用时间戳+随机数防止重复
        // 设置上传文件名
        SimpleDateFormat fileFormatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        // 源文件重命名,文件命名格式:yyyyMMddHHmmssSSS
        String fileName = fileFormatter.format(new Date()) + new Random().nextInt(1000) + "." + suffix;

        String realFilePath = filePath + fileName;
        // 转存文件
        file.transferTo(new File(realFilePath));

        //如果是jpg图片或png图片，且图片大小超过要求的尺寸，则进行压缩处理
        if (("jpg".equalsIgnoreCase(suffix) || "jpeg".equalsIgnoreCase(suffix)|| "png".equalsIgnoreCase(suffix)) &&
                compKB > 0 && file.getSize() > compKB * 1024) {
            //压缩
            String compFileName = "thumb_" + fileName;
            compFileName = compFileName.toLowerCase();
            if(compFileName.contains(".png")){
                compFileName = compFileName.replace(".png", ".jpg");
            }
            cycleCommpress(realFilePath, filePath + compFileName, 1f, compKB);
            return relativePath + compFileName;
        } else {

            if (logger.isDebugEnabled()) {
                logger.debug("文件 [{}] 上传成功，目录 [{}]", originalName, realFilePath);
            }

            return relativePath + fileName;
        }
    }

    /**
     * 循环压缩，直到合适大小
     * @param srcPath
     * @param destPath
     * @throws IOException
     * @author caiys/2018年5月21日
     */
    private void cycleCommpress(String srcPath, String destPath, float quality, int compKB) throws IOException {
        Thumbnails.of(srcPath).size(1000,1000).outputQuality(quality).toFile(destPath);
        File thumbFile = new File(destPath);
        if (thumbFile.length() >= compKB*1024) {	// 大于最大值，再次压缩
            thumbFile.delete();	// 删除源文件，quality不会随图片的减小而减小，所以重新压缩改变quality大小即可
            quality = quality - 0.1f;
            if (quality <= 0) {
                return ;
            }
            cycleCommpress(srcPath, destPath, quality, compKB);
        } else {
            return ;
        }
    }

    /**
     * Page对象转成html代码
     * @param page Page分页对象
     * @return 用于页面分页展示的html代码
     */
    protected String pageToFrontHTML(Page page) {
        if (page == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();

        long pageNo = page.getCurrent();
        long pageSize = page.getSize();
        long first = 1;
        long total = page.getTotal();
        long prev, next;
        int length = 8;
        int slider = 1;
        long last = (total / pageSize + first - 1);
        if (total % pageSize != 0 || last == 0) {
            last++;
        }

        if (last < first) {
            last = first;
        }

        if (pageNo <= 1) {
            pageNo = first;
        }

        if (pageNo >= last) {
            pageNo = last;
        }

        if (pageNo < last - 1) {
            next = pageNo + 1;
        } else {
            next = last;
        }

        if (pageNo > 1) {
            prev = pageNo - 1;
        } else {
            prev = first;
        }

        if (pageNo > last) {// 如果当前页大于尾页
            pageNo = last;
        }

        if (pageNo == first) {// 如果是首页
            sb.append("<li class=\"disabled\"><a href=\"javascript:\">&#171; 上一页</a></li>\n");
        } else {
            sb.append("<li><a href=\"javascript:page(" + prev + "," + pageSize + ");\">&#171; 上一页</a></li>\n");
        }

        long begin = pageNo - (length / 2);

        if (begin < first) {
            begin = first;
        }

        long end = begin + length - 1;

        if (end >= last) {
            end = last;
            begin = end - length + 1;
            if (begin < first) {
                begin = first;
            }
        }

        if (begin > first) {
            long i = 0;
            for (i = first; i < first + slider && i < begin; i++) {
                sb.append("<li><a href=\"javascript:page(" + i + "," + pageSize + ");\">"
                        + (i + 1 - first) + "</a></li>\n");
            }
            if (i < begin) {
                sb.append("<li class=\"disabled\"><a href=\"javascript:\">...</a></li>\n");
            }
        }

        for (long i = begin; i <= end; i++) {
            if (i == pageNo) {
                sb.append("<li class=\"active\"><a href=\"javascript:\">" + (i + 1 - first)
                        + "</a></li>\n");
            } else {
                sb.append("<li><a href=\"javascript:page(" + i + "," + pageSize + ");\">"
                        + (i + 1 - first) + "</a></li>\n");
            }
        }

        if (last - end > slider) {
            sb.append("<li class=\"disabled\"><a href=\"javascript:\">...</a></li>\n");
            end = last - slider;
        }

        for (long i = end + 1; i <= last; i++) {
            sb.append("<li><a href=\"javascript:page(" + i + "," + pageSize + ");\">"
                    + (i + 1 - first) + "</a></li>\n");
        }

        if (pageNo == last) {
            sb.append("<li class=\"disabled\"><a href=\"javascript:\">下一页 &#187;</a></li>\n");
        } else {
            sb.append("<li><a href=\"javascript:page(" + next + "," + pageSize + ");\">"
                    + "下一页 &#187;</a></li>\n");
        }

        sb.append("<li class=\"disabled controls\"><a href=\"javascript:\">当前 ");
        sb.append("<input disabled=\"disabled\" type=\"text\"  value=\"" + pageNo + "\" onkeypress=\"__pageNoChange(event,this)\"");
        sb.append(" onclick=\"this.select();\"/> / ");
        float pageNumber = total / pageSize;
        if (pageNumber < 1) {
            pageNumber = 1;
        }
        sb.append("<input type=\"text\" disabled=\"disabled\" value=\"" + (int) Math.ceil(pageNumber) + "\" onkeypress=\"__pageSizeChange(event,this)\"");
        sb.append(" onclick=\"this.select();\"/> 页，");
        sb.append("共 " + total + " 条" + "</a><li>\n");

        sb.insert(0, "<ul>\n").append("</ul>\n");

        sb.append("<script>\n");
        sb.append("function __pageNoChange(e, __this){var evt=e||window.event||__this;var c=e.keyCode||e.which;");
        sb.append("if(c==13) page(__this.value," + pageSize + ");}\n");
        sb.append("function __pageSizeChange(e, __this){var evt=e||window.event||__this;var c=e.keyCode||e.which;");
        sb.append("if(c==13) page(" + pageNo + ",__this.value);}\n");
        sb.append("</script>\n");

        sb.append("<div style=\"clear:both;\"></div>");

//		sb.insert(0,"<div class=\"page\">\n").append("</div>\n");

        return sb.toString();
    }

}
